# Replication for "When group appeals backfire: explaining the asymmetric effects of place-based appeals"
# Authors: Lukas Haffert, Tabea Palmtag, Dominik Schraff

# Main paper - Analysis
# This file replicates the analysis and figures included in the paper, and the corresponding tables in the appendix
rm(list=ls(all=T))

knitr::opts_chunk$set(echo = TRUE, warnings=F, message=F, warning=F)
p_needed <- c("tidyverse","dplyr", "hrbrthemes","viridis", "rstatix", "stargazer", "sjPlot", "list", "margins")
lapply(p_needed, require, character.only = TRUE)

# Data survey I UK & GER ----
ger <- readRDS("germany_surveyI.Rds")
uk <- readRDS("uk_surveyI.Rds")

# Candidate Evaluation Study I (Figure 2 / Appendix D) ----
m_ger <- lm(eval_candidate ~ condition*urban, data = ger)
m_uk <- lm(eval_candidate ~ condition*urban, data = uk)

ger.data <- expand.grid(intercept=1, 
                        condition=unique(ger$condition), 
                        urban=c("rural", "urban"))

coef_ger <- data.frame(term=predict(m_ger, ger.data, se=T)$fit,
                       se=predict(m_ger, ger.data, se=T)$se.fit)%>%
  bind_cols(ger.data) %>%
  mutate(conf.low=term-2*se,
         conf.high=term+2*se) %>%
  mutate(Country = "Germany")

uk.data <- expand.grid(intercept=1, 
                       condition=unique(uk$condition), 
                       urban=c("rural", "urban"))

coef_uk <- data.frame(term=predict(m_uk, uk.data, se=T)$fit,
                      se=predict(m_uk, uk.data, se=T)$se.fit)%>%
  bind_cols(uk.data) %>%
  mutate(conf.low=term-2*se,
         conf.high=term+2*se) %>%
  mutate(Country = "UK")

farben <- c("black","black")
position <- position_dodge2(width=.2)

## Figure 2a) ----
ggplot(coef_ger, aes(y = term, x = condition))+
  geom_point(aes(shape = urban), position=position, size=2.5) +
  geom_linerange(aes(ymin = conf.low, ymax = conf.high), position=position)+
  labs(title = "Candidate Evaluation Germany")+
  scale_color_manual(values=farben)+
  labs(x="",y="")+
  theme_bw()+
  theme(legend.position="right", legend.title=element_blank(), axis.ticks = element_blank(),
        axis.text.y = element_text(size = 20), legend.text = element_text(size = 20), 
        axis.text.x = element_text(size = 20), plot.title = element_text(size = 25))

## Figure 2b) ----
ggplot(coef_uk, aes(y = term, x = condition))+
  geom_point(aes(shape = urban), position=position, size=2.5) +
  geom_linerange(aes(ymin = conf.low, ymax = conf.high), position=position)+
  labs(title = "Candidate Evaluation UK")+
  scale_color_manual(values=farben)+
  labs(x="",y="")+
  theme_bw()+
  theme(legend.position="right", legend.title=element_blank(), axis.ticks = element_blank(),
        axis.text.y = element_text(size = 20), legend.text = element_text(size = 20), 
        axis.text.x = element_text(size = 20), plot.title = element_text(size = 25))

## Table D1 ----
stargazer(m_ger, m_uk,
          dep.var.labels =	"Evaluation of Candidate",
          column.labels = c("Germany", "UK"),
          covariate.labels = c("Symbolic Appeal", "Economic Appeal", "Cultural Appeal", "Urban ID", 
                               "Symbolic Appeal x Urban ID",  "Economic Appeal x Urban ID", "Cultural Appeal x Urban ID"),
          table.placement = "ht!", column.sep.width = "0pt",
          label = "m_general",
          digits = 2,
          title = "",
          type="text")

# Strength of place-based identity and candidate evaluation (Figure 3) ----
m_ger1 <- lm(eval_candidate ~ treated*identity, data = ger %>% filter(urban=="urban"))
m_ger2 <- lm(eval_candidate ~ treated*identity, data = ger %>% filter(urban=="rural"))

m_uk1 <- lm(eval_candidate ~ treated*identity, data = uk %>% filter(urban=="urban"))
m_uk2 <- lm(eval_candidate ~ treated*identity, data = uk %>% filter(urban=="rural"))

ger.data <- expand.grid(intercept=1, 
                        treated=unique(ger$treated), 
                        identity=c("low", "high"))

coef_ger <- data.frame(term=predict(m_ger1, ger.data, se=T)$fit,
                       se=predict(m_ger1, ger.data, se=T)$se.fit)%>%
  bind_cols(ger.data) %>%
  mutate(conf.low=term-2*se,
         conf.high=term+2*se) %>%
  mutate(urban = "Urban")

coef_ger2 <- data.frame(term=predict(m_ger2, ger.data, se=T)$fit,
                        se=predict(m_ger2, ger.data, se=T)$se.fit)%>%
  bind_cols(ger.data) %>%
  mutate(conf.low=term-2*se,
         conf.high=term+2*se) %>%
  mutate(urban = "Rural") 
coef_ger <- rbind(coef_ger,coef_ger2)

uk.data <- expand.grid(intercept=1, 
                       treated=unique(uk$treated), 
                       identity=c("low", "high"))

coef_uk <- data.frame(term=predict(m_uk1, uk.data, se=T)$fit,
                      se=predict(m_uk1, uk.data, se=T)$se.fit)%>%
  bind_cols(uk.data) %>%
  mutate(conf.low=term-2*se,
         conf.high=term+2*se) %>%
  mutate(urban = "Urban") 
coef_uk2 <- data.frame(term=predict(m_uk2, uk.data, se=T)$fit,
                       se=predict(m_uk2, uk.data, se=T)$se.fit)%>%
  bind_cols(uk.data) %>%
  mutate(conf.low=term-2*se,
         conf.high=term+2*se) %>%
  mutate(urban = "Rural") 
coef_uk <- rbind(coef_uk,coef_uk2)

## Figure 3a) ----
ggplot(coef_ger, aes(y = term, x = identity))+
  geom_point(aes(shape = treated), position=position, size=2.5) +
  geom_linerange(aes(ymin = conf.low, ymax = conf.high), position=position)+
  labs(title = "Candidate Evaluation Germany")+
  scale_color_manual(values=farben)+
  scale_x_discrete(name ="Identification") +
  labs(x="",y="")+
  theme_bw()+
  theme(legend.position="right", legend.title=element_blank(), axis.ticks = element_blank(),
        axis.text.y = element_text(size = 20), legend.text = element_text(size = 20),  
        axis.text.x = element_text(size = 20), plot.title = element_text(size = 25), strip.text.x = element_text(size = 20), axis.title.x = element_text(size = 20)) + facet_wrap(~ urban)

## Figure 3b) ----
ggplot(coef_uk, aes(y = term, x = identity))+
  geom_point(aes(shape = treated), position=position, size=2.5) +
  geom_linerange(aes(ymin = conf.low, ymax = conf.high), position=position)+
  labs(title = "Candidate Evaluation UK")+
  scale_color_manual(values=farben)+
  scale_x_discrete(name ="Identification") +
  labs(x="",y="")+
  theme_bw()+
  theme(legend.position="right", legend.title=element_blank(), axis.ticks = element_blank(),
        axis.text.y = element_text(size = 20), legend.text = element_text(size = 20),  
        axis.text.x = element_text(size = 20), plot.title = element_text(size = 25), strip.text.x = element_text(size = 20), axis.title.x = element_text(size = 20)) + facet_wrap(~ urban)

# Data survey II GER ----
df <- readRDS("germany_surveyII.Rds")

# Candidate Evaluation Study II (Figure 4 and Appendix F1) ----
m1 <- lm(eval_candidate ~ condition, data = df)

coef <- tidy(m1, conf.int = TRUE) %>%
  filter(term != "(Intercept)") %>%
  mutate(Category = ifelse(term=="conditionRural", "Original Appeals", 
                           ifelse(term=="conditionUrban", "Original Appeals",
                                  ifelse(term=="conditionAntagonistic/Innovation", "Antagonistic",
                                         ifelse(term=="conditionAntagonistic/Rent", "Antagonistic",
                                                ifelse(term == "conditionHarmonious/Innovation", "Harmonious",
                                                       ifelse(term =="conditionHarmonious/Rent", "Harmonious", NA))))))) %>%
  mutate(Category = fct_relevel(Category, "Original Appeals", "Antagonistic", "Harmonious")) %>%
  mutate(term =  ifelse(term=="conditionRural", "Rural", 
                        ifelse(term=="conditionUrban", "Urban",
                               ifelse(term=="conditionAntagonistic/Innovation", "Innovation",
                                      ifelse(term=="conditionAntagonistic/Rent", "Rent",
                                             ifelse(term == "conditionHarmonious/Innovation", "Innovation",
                                                    ifelse(term =="conditionHarmonious/Rent", "Rent", NA))))))) 

farben <- c("black","black","black")

## Figure 4) ----
ggplot(coef, aes(x = estimate, y = (term), color = Category))+
  geom_point(aes(shape = Category), size=3) +
  geom_linerange(aes(xmin = conf.low, xmax = conf.high))+
  geom_vline(xintercept=0, colour = gray(1/2), lty = 2)+
  labs(title = "Candidate Evaluation")+
  scale_color_manual(values=farben)+
  labs(x="",y="")+
  theme_bw()+
  facet_grid(Category ~ ., scale = 'free_y', switch ="y")  +
  theme(panel.spacing = unit(0, "lines"), 
        strip.background = element_blank(),
        strip.placement = "outside", axis.ticks = element_blank(), panel.grid.minor = element_blank(), legend.position="none",
        axis.text.y = element_text(size = 20), legend.text = element_text(size = 20), legend.title = element_text(size = 20), 
        axis.text.x = element_text(size = 10), plot.title = element_text(size = 25), strip.text.y = element_text(size = 15))

## Table F1 ----
stargazer(m1,
          dep.var.labels =	"Evaluation of Candidate (Survey 2)",
          covariate.labels = c("Urban", "Rural", "Antagonistic/Innovation", "Antagonistic/Rent", "Harmonious/Innovation", "Harmonious/Rent"),
          table.placement = "ht!", column.sep.width = "0pt",
          label = "m_survey2",
          digits = 2,
          title = "",
          type="text")

# Identity and Resetment among Urbanites, study II (Figure 5 and Appendix F2 and F3) ----
# Filter out Urban and Rural Treatment from Study I
df1 <- df %>% filter(condition != "Urban", condition != "Rural")
m2 <- lm(eval_candidate ~ conditionII*id_res, data = df1)

new.data <- expand.grid(intercept=1, 
                        conditionII=unique(df1$conditionII),
                        id_res=c("id low", "id high/res low", "id high/res high"))

coef_df <- data.frame(term=predict(m2, new.data, se=T)$fit,
                      se=predict(m2, new.data, se=T)$se.fit)%>%
  bind_cols(new.data) %>%
  mutate(conf.low=term-2*se,
         conf.high=term+2*se) 

farben <- c("black","black")
position <- position_dodge2(width=.3)

## Figure 5 ----
ggplot(coef_df, aes(y = conditionII, x = term))+
  geom_point(aes(shape = id_res), position=position, size=3) +
  geom_linerange(aes(xmin = conf.low, xmax = conf.high), position=position)+
  labs(title = "Candidate Evaluation")+
  scale_color_manual(values=farben)+
  labs(x="Identification & Resentment",y="", shape="")+
  theme_bw()+
  theme(panel.spacing = unit(0, "lines"), axis.ticks = element_blank(), panel.grid.minor = element_blank(), 
        legend.position="bottom", legend.box="vertical", axis.title.x=element_text(size = 20),
        axis.text.y = element_text(size = 20), legend.text = element_text(size = 20), legend.title = element_text(size = 20), 
        axis.text.x = element_text(size = 20), plot.title = element_text(size = 25), strip.text.y = element_text(size = 15))+
  guides(fill=guide_legend(nrow=2,byrow=TRUE))


## Table F2 (pooled antagnoistic and harmonious treatments) ----
stargazer(m2, 
          dep.var.labels =	"Evaluation of Candidate",
          covariate.labels = c("Antagonistic", "Harmonious", "High Identity/Low Resentment", "High Identity/High Resentment", "Antagonistic x High Identity/Low Resentment", "Harmonious x High Identity/Low Resentment", "Antagonistic x High Identity/High Resentment", "Harmonious x High Identity/High Resentment"),
          table.placement = "ht!", column.sep.width = "0pt",
          label = "m_identity_resent_pooled",
          digits = 2,
          title = "",
          type="text")

## Table F3 (all treatments separately) ----
m3 <- lm(eval_candidate ~ condition*id_res, data = df1)

stargazer(m3, 
          dep.var.labels =	"Evaluation of Candidate",
          covariate.labels = c("Antagonistic/Innovation", "Antagonistic/Rent", "Harmonious/Innovation", "Harmonious/Rent", "High Identity/Low Resentment", "High Identity/High Resentment", 
                               "Antagonistic/Innovation x High Identity/Low Resentment",  "Antagonistic/Rent x High Identity/Low Resentment", "Harmonious/Innovation x High Identity/Low Resentment",
                               "Harmonious/Rent x High Identity/Low Resentment", "Antagonistic/Innovation x High Identity/High Resentment", "Antagonistic/Rent x High Identity/High Resentment", 
                               "Harmonious/Innovation x High Identity/High Resentment","Harmonious/Rent x High Identity/High Resentment"),
          table.placement = "ht!", column.sep.width = "0pt",
          label = "m_identity_resent_reduced",
          digits = 2,
          title = "",
          type="text")

# Effect of treatment on candidate evaluation by representation ideal, study II (Figure 6 and Appendix G1) ----
m4 <- lm(eval_candidate ~ condition*Representation, data = df1)

new.data <- expand.grid(intercept=1, 
                        condition=unique(df1$condition), 
                        Representation=c("particularistic", "universalist"))

coef_df <- data.frame(term=predict(m4, new.data, se=T)$fit,
                      se=predict(m4, new.data, se=T)$se.fit)%>%
  bind_cols(new.data) %>%
  mutate(Category = ifelse(condition=="Antagonistic/Innovation", "Antagonistic",
                           ifelse(condition=="Antagonistic/Rent", "Antagonistic",
                                  ifelse(condition == "Harmonious/Innovation", "Harmonious",
                                         ifelse(condition =="Harmonious/Rent", "Harmonious", 
                                                ifelse(condition == "Control", "", NA)))))) %>%
  mutate(Category = factor(Category,levels = c("","Antagonistic", "Harmonious"))) %>%
  mutate(conf.low=term-2*se,
         conf.high=term+2*se) %>%
  mutate(condition = ifelse(condition=="Antagonistic/Innovation", "Innovation",
                            ifelse(condition=="Antagonistic/Rent", "Rent",
                                   ifelse(condition == "Harmonious/Innovation", "Innovation",
                                          ifelse(condition =="Harmonious/Rent", "Rent", 
                                                 ifelse(condition == "Control", "Control", NA)))))) 

## Figure 6 ----
ggplot(coef_df, aes(y = condition, x = term))+
  geom_point(aes(shape = Representation), position=position, size=3) +
  geom_linerange(aes(xmin = conf.low, xmax = conf.high), position=position)+
  labs(title = "Candidate Evaluation")+
  scale_color_manual(values=farben)+
  labs(x="",y="")+
  theme_bw()+
  facet_grid(Category ~ ., scale = 'free_y', switch ="y")  +
  theme(panel.spacing = unit(0, "lines"), 
        strip.background = element_blank(),
        strip.placement = "outside", axis.ticks = element_blank(), panel.grid.minor = element_blank(), 
        legend.position="right",
        axis.text.y = element_text(size = 20), legend.text = element_text(size = 15), legend.title = element_text(size = 15), 
        axis.text.x = element_text(size = 20), plot.title = element_text(size = 25), strip.text.y = element_text(size = 15))


## Appendix G: Table G1 ----
stargazer(m4, 
          dep.var.labels =	"Evaluation of Candidate",
          covariate.labels = c("Antagonistic/Innovation", "Antagonistic/Rent", "Harmonious/Innovation", "Harmonious/Rent", "Universalist", "Antagonistic/Innovation x Universalist", "Antagonistic/Rent x Universalist", "Harmonious/Innovation x Universalist", "Harmonious/Rent x Universalist"),
          table.placement = "ht!", column.sep.width = "0pt",
          label = "m_universalist",
          digits = 2,
          title = "",
          type="text")

# Effect of treatment on candidate evaluation by by out-group deservingness, study II (Figure 7 and Appendix G2) ----
m5 <- lm(eval_candidate ~ condition*Deservigness, data = df1)

new.data <- expand.grid(intercept=1, 
                        condition=unique(df1$condition), 
                        Deservigness=c("low", "high"))

coef_df <- data.frame(term=predict(m5, new.data, se=T)$fit,
                      se=predict(m5, new.data, se=T)$se.fit)%>%
  bind_cols(new.data) %>%
  mutate(Category = ifelse(condition=="Antagonistic/Innovation", "Antagonistic",
                           ifelse(condition=="Antagonistic/Rent", "Antagonistic",
                                  ifelse(condition == "Harmonious/Innovation", "Harmonious",
                                         ifelse(condition =="Harmonious/Rent", "Harmonious", 
                                                ifelse(condition == "Control", "", NA)))))) %>%
  mutate(Category = factor(Category,levels = c("","Antagonistic", "Harmonious"))) %>%
  mutate(conf.low=term-2*se,
         conf.high=term+2*se) %>%
  mutate(condition = ifelse(condition=="Antagonistic/Innovation", "Innovation",
                            ifelse(condition=="Antagonistic/Rent", "Rent",
                                   ifelse(condition == "Harmonious/Innovation", "Innovation",
                                          ifelse(condition =="Harmonious/Rent", "Rent", 
                                                 ifelse(condition == "Control", "Control", NA)))))) 

## Figure 7 ----
ggplot(coef_df, aes(y = condition, x = term))+
  geom_point(aes(shape = Deservigness), position=position, size=3) +
  geom_linerange(aes(xmin = conf.low, xmax = conf.high), position=position)+
  labs(title = "Candidate Evaluation")+
  scale_color_manual(values=farben)+
  labs(x="",y="")+
  theme_bw()+
  facet_grid(Category ~ ., scale = 'free_y', switch ="y")  +
  theme(panel.spacing = unit(0, "lines"), 
        strip.background = element_blank(),
        strip.placement = "outside", axis.ticks = element_blank(), panel.grid.minor = element_blank(), 
        legend.position="right",
        axis.text.y = element_text(size = 20), legend.text = element_text(size = 20), legend.title = element_text(size = 20), 
        axis.text.x = element_text(size = 20), plot.title = element_text(size = 25), strip.text.y = element_text(size = 15))

## Appendix G: Table G2 ----
stargazer(m5, 
          dep.var.labels =	"Evaluation of Candidate",
          covariate.labels = c("Antagonistic/Innovation", "Antagonistic/Rent", "Harmonious/Innovation", "Harmonious/Rent", "Deservingness", "Antagonistic/Innovation x Deservingness", "Antagonistic/Rent x Deservingness", "Harmonious/Innovation x Deservingness", "Harmonious/Rent x Deservingness"),
          table.placement = "ht!", column.sep.width = "0pt",
          label = "m_deservign",
          digits = 2,
          title = "",
          type="text")

# Effect of treatment on candidate evaluation by by objective economic conditions, study II (Figure 8 and Appendix G3) ----
m6 <- lm(eval_candidate ~ condition*`Welfare Quota`, data = df1)

new.data <- expand.grid(intercept=1, 
                        condition=unique(df1$condition), 
                        `Welfare Quota`= c("low", "high"))

coef_df <- data.frame(term=predict(m6, new.data, se=T)$fit,
                      se=predict(m6, new.data, se=T)$se.fit)%>%
  bind_cols(new.data) %>%
  mutate(Category = ifelse(condition=="Antagonistic/Innovation", "Antagonistic",
                           ifelse(condition=="Antagonistic/Rent", "Antagonistic",
                                  ifelse(condition == "Harmonious/Innovation", "Harmonious",
                                         ifelse(condition =="Harmonious/Rent", "Harmonious", 
                                                ifelse(condition == "Control", "", NA)))))) %>%
  mutate(Category = factor(Category,levels = c("","Antagonistic", "Harmonious"))) %>%
  mutate(conf.low=term-2*se,
         conf.high=term+2*se) %>%
  mutate(condition = ifelse(condition=="Antagonistic/Innovation", "Innovation",
                            ifelse(condition=="Antagonistic/Rent", "Rent",
                                   ifelse(condition == "Harmonious/Innovation", "Innovation",
                                          ifelse(condition =="Harmonious/Rent", "Rent", 
                                                 ifelse(condition == "Control", "Control", NA)))))) 


## Figure 8 ----
ggplot(coef_df, aes(y = condition, x = term))+
  geom_point(aes(shape = `Welfare Quota`), position=position, size=3) +
  geom_linerange(aes(xmin = conf.low, xmax = conf.high), position=position)+
  #geom_vline(xintercept=0, colour = gray(1/2), lty = 2)+
  labs(title = "Candidate Evaluation")+
  scale_color_manual(values=farben)+
  labs(x="",y="")+
  theme_bw()+
  facet_grid(Category ~ ., scale = 'free_y', switch ="y")  +
  theme(panel.spacing = unit(0, "lines"), 
        strip.background = element_blank(),
        strip.placement = "outside", axis.ticks = element_blank(), panel.grid.minor = element_blank(), 
        legend.position="right",
        axis.text.y = element_text(size = 20), legend.text = element_text(size = 20), legend.title = element_text(size = 20), 
        axis.text.x = element_text(size = 20), plot.title = element_text(size = 25), strip.text.y = element_text(size = 15))

## Appendix G: Table G3 ----
stargazer(m6,
          dep.var.labels =	"Evaluation of Candidate (Survey 2)",
          covariate.labels = c("Antagonistic/Innovation", "Antagonistic/Rent", "Harmonious/Innovation", "Harmonious/Rent", "Welfare Quota", "Antagonistic/Innovation x Welfare Quota", "Antagonistic/Rent x Welfare Quota", "Harmonious/Innovation x Welfare Quoat", "Harmonious/Rent x Welfare Quota"),
          table.placement = "ht!", column.sep.width = "0pt",
          label = "m_context",
          digits = 2,
          title = "",
          type="text")  

# Average likelihood of candidate party affiliation by condition, study II -----
parties <- df %>% dplyr::select(condition, candidate_spd, candidate_cdu, candidate_fdp, candidate_gruen, candidate_afd, candidate_linke) %>% 
  group_by(condition) %>%
  summarise_at(vars("candidate_spd", "candidate_cdu", "candidate_fdp", "candidate_gruen", "candidate_afd", "candidate_linke"), mean, na.rm =T)

long_data <- pivot_longer(parties, 
                          cols = starts_with("candidate"), 
                          names_to = c(".value", "Party"), 
                          names_sep = "_") 
long_data$Party[long_data$Party == "spd"] <- "SPD"
long_data$Party[long_data$Party == "fdp"] <- "FDP"
long_data$Party[long_data$Party == "gruen"] <- "Greens"
long_data$Party[long_data$Party == "afd"] <- "AfD"
long_data$Party[long_data$Party == "cdu"] <- "CDU"
long_data$Party[long_data$Party == "linke"] <- "Left"

long_data <- long_data %>% filter(condition != "Urban") %>% filter(condition != "Rural") %>%
  mutate(Party = factor(Party, levels = c("Left", "SPD", "Greens", "FDP", "CDU", "AfD")))

pcol <- coalitions::party_colors_de

## Figure 9 ----
ggplot(long_data, aes(x = candidate, y = condition, shape = Party, group = Party, color=Party)) +
  geom_point(position = position_dodge(width = 0), size = 3) +
  labs(title = "")+
  labs(x="Average Likelihood of Candidate Party Affiliation",y="")+
  theme_bw() +
  scale_color_manual(values=pcol)+
  theme(panel.spacing = unit(0, "lines"), 
        strip.background = element_blank(),
        strip.placement = "outside", axis.ticks = element_blank(), panel.grid.minor = element_blank(), 
        legend.position="right",
        axis.text.y = element_text(size = 15), legend.text = element_text(size = 15), legend.title = element_text(size = 15), 
        axis.text.x = element_text(size = 15), plot.title = element_text(size = 15), strip.text.y = element_text(size = 15)) 

